﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Box.Entities;
using Microsoft.Practices.ObjectBuilder2;

namespace Box.Repository
{
    public class VentaRepository : MasterRepository, IVentaRepository
    {
       // public ISerieComprabanteRepository SerieComprabanteRepository { get; set; }
       

        public List<Venta> GetAllFromVenta()
        {
            var query = (from c in Context.Ventas
                        .Include("Cliente")
                        .Include("DetalleVenta.Producto")
                        where c.estadoVenta == true
                        
                        select c).Take(50);
            return query.ToList();
        }

        //public List<Venta> GetFromVentaByCriterio(string criterio)
        //{
        //    var query = (from c in Context.Ventas
        //                .Include("Cliente")
        //                .Include("DetalleVenta.Producto")
        //                 where c.estadoVenta == true
        //                select c).Take(45);
        //    if (criterio != null && criterio != string.Empty)
        //    {
        //        query = (query.Where(p => p.Cliente.NombreCliente.ToUpper().Contains(criterio.ToUpper())
        //                                 || p.Cliente.RucCliente.Equals(criterio.ToUpper()) && p.estadoVenta==true)).Take(35);
        //    }
        //    return query.ToList();
        //}

        public Venta GetFromVentaById(int id)
        {
            var query = from p in Context.Ventas
                        .Include("Cliente")
                        .Include("DetalleVenta.Producto")
                        where p.Id.Equals(id)
                        select p;
            return query.SingleOrDefault();
        }

        public void AddVenta(Venta venta)
        {
            var newVenta = new Venta();
            newVenta.ClienteId = venta.ClienteId;
            newVenta.Igv = venta.Igv;
            // newVenta.Cliente = venta.Cliente;
            newVenta.Fecha = venta.Fecha;
            newVenta.Total = venta.Total;
            newVenta.IdTipoDocumento = venta.IdTipoDocumento;
            //newVenta.TipoDocumento = venta.TipoDocumento;
            newVenta.estadoVenta = true;
            foreach (var item in venta.DetalleVenta)
            {
                var detalle = new DetalleVenta();
                detalle.Cantidad = item.Cantidad;
                detalle.IdProducto = item.IdProducto;

                detalle.PrecioUnit = item.PrecioUnit;//TIPO DOC

                newVenta.DetalleVenta.Add(detalle);
            }


            Context.Ventas.Add(newVenta);
            Context.SaveChanges();
 

            //venta.DetalleVenta.
            //    ForEach(i=>Context.Entry(i.Producto)
            //        .State=EntityState.Unchanged);

        
           
        }

        public void UpdateVenta(Venta venta)
        {
            var ventaDB = GetFromVentaById(venta.Id);

            ventaDB.Fecha = venta.Fecha;
            ventaDB.Total = venta.Total;
            ventaDB.IdTipoDocumento = venta.IdTipoDocumento;

            if (ventaDB.ClienteId != venta.ClienteId)
            {
                ventaDB.ClienteId = venta.ClienteId;
                ventaDB.Cliente = venta.Cliente;
                Context.Entry(ventaDB.Cliente).State = EntityState.Unchanged;
            }



            var DetallesEliminados = new List<DetalleVenta>();

            foreach (var detalleBD in ventaDB.DetalleVenta)
            {
                var eliminado = venta.DetalleVenta
                    .Where(dp => dp.Item == detalleBD.Item)
                    .SingleOrDefault();

                if (eliminado == null)
                {
                    DetallesEliminados.Add(detalleBD);
                }
            }

            foreach (var detEliminado in DetallesEliminados)
            {
                var eliminar = ventaDB.DetalleVenta.Where(dp => dp.Item == detEliminado.Item).SingleOrDefault();
                ventaDB.DetalleVenta.Remove(eliminar);

            }


            foreach (var detalle in venta.DetalleVenta)
            {
                //nuevos detalles
                if (detalle.Item == 0)
                {
                    Context.Entry(detalle.Producto).State = EntityState.Unchanged;
                    ventaDB.DetalleVenta.Add(detalle);
                }
                else//modificados
                {
                    var detalleDB = ventaDB.DetalleVenta.Where(dp => dp.Item == detalle.Item).SingleOrDefault();

                    detalleDB.Cantidad = detalle.Cantidad;
                    detalleDB.PrecioUnit = detalle.PrecioUnit;

                    Context.Entry(detalleDB.Producto).State = EntityState.Unchanged;
                    Context.Entry(detalleDB).State = EntityState.Modified;

                }
            }

            Context.Entry(ventaDB).State = EntityState.Modified;

            Context.SaveChanges();
        }

        public void RemoveVenta(int id)
        {
            var existe = Context.Ventas.Find(id);
            if (existe != null)
            {
                Context.Entry(existe).State=EntityState.Modified;
                existe.estadoVenta = false;
                
                Context.SaveChanges();
               
                
            }
            
        }

        public List<int> AumentarStock(int idProducto, decimal cantidad)
        {
            var query = Context.Database.SqlQuery<int>("exec dbo.disminuir_stock @idproducto='" + idProducto + "'," + " @cantidad='" + cantidad + "'");
            return query.ToList();
        }

        public bool ExisteVenta(int id)
        {
            var query = Context.Ventas.Where(p => p.Id.Equals(id));

            return query.Any();
        }

        public List<Decimal> ListVent(int anio)
        {
            var query = Context.Database.SqlQuery<Decimal>("exec dbo.spRepVenta @fecha='" + anio + "'");
            return query.ToList();
        }

        public List<Venta> GetFromVentasByRangoFechas(DateTime fechaI, DateTime fechaF)
        {

            var query = from p in Context.Ventas
                where p.Fecha >= fechaI && p.Fecha <= fechaF
                select p;
                return query.ToList();       
        }
        public List<Venta> GetFromVentasByAnio(int anio)
        {

           // var prueba = ListVent(anio);
                var query = Context.Database.SqlQuery<Venta>("exec dbo.spRepVenta @fecha='" + anio + "'");
                return query.ToList();

        }


        public List<Venta> GetFRomVentasAnuladadByCriterio(string criterio)
        {
            var query = from p in Context.Ventas
                        .Include("Cliente")
                        .Include("DetalleVenta.Producto")
                where p.estadoVenta == false
                
                select p;
            if (criterio!=null && criterio!=string.Empty)
            {
                query = from p in query
                        .Include("Cliente")
                        .Include("DetalleVenta.Producto")
                    where p.Cliente.NombreCliente.ToUpper().Contains(criterio.ToUpper())
                    && p.estadoVenta==false
                    select p;
            }
            return query.ToList();
        }


        public string GetNetxtNroBoleta()
        {
            var nroSerie = Context.SerieComprobantes.SingleOrDefault();
            var nroBoleta = Context.Ventas
                //.Where(v => v.TipoDocumento
                //   .NombreTipoDocumento
                //   .Equals("BOLETA"))
                    .Max(v => v.Correlativo);

            return nroBoleta;
           // throw new NotImplementedException();
        }


        public IEnumerable<Venta> GetFromVentaByCriterio(string criterio, bool? anulados, bool? todos)
        {
            var query = from p in Context.Ventas
                        .Include("Cliente")
                        .Include("DetalleVenta.Producto")
                        select p;

            if (todos.HasValue && anulados.HasValue)
            {
                if (!todos.Value)
                {
                    query = from p in query
                            .Include("Cliente")
                        .Include("DetalleVenta.Producto")
                            where p.estadoVenta == anulados.Value
                            select p;
                }

            }

            if (!string.IsNullOrEmpty(criterio))
            {
                query = from p in query
                        .Include("Cliente")
                        .Include("DetalleVenta.Producto")
                        where p.Cliente.NombreCliente.ToUpper().Contains(criterio.ToUpper()) ||
                        p.Cliente.RucCliente.ToUpper().Contains(criterio.ToUpper())

                        select p;
            }
            return query;
        }
    }
}
